#!/usr/bin/env node
var cp = require('./utils/child-process-wrapper.js');
var crypto = require('crypto')
var fingerprint = require('./utils/fingerprint')
var fs = require('fs');
var path = require('path');

process.chdir(path.dirname(__dirname));

var homeDir = process.platform == 'win32' ? process.env.USERPROFILE : process.env.HOME;

function loadEnvironmentVariables(filePath) {
  try {
    var lines = fs.readFileSync(filePath, 'utf8').trim().split('\n');
    for (i in lines) {
      var parts = lines[i].split('=');
      var key = parts[0].trim();
      var value = parts[1].trim().substr(1, parts[1].length - 2);
      process.env[key] = value;
    }
  } catch(error) {
    console.error("Failed to load environment variables: " + filePath, error.code);
  }
}

function readEnvironmentVariables() {
  if (process.env.JANKY_SHA1) {
    if (process.platform === 'win32') {
      loadEnvironmentVariables(path.resolve('/jenkins/config/atomcredentials'));
    } else if (process.platform === 'darwin') {
      loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials');
      loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain');
    }
  }
}

function setEnvironmentVariables() {
  if (process.platform === 'linux') {
    // Use Clang for building native code, the GCC on Precise is too old.
    process.env.CC = 'clang';
    process.env.CXX = 'clang++';
    process.env.npm_config_clang = '1';
  } else if (process.platform === 'win32') {
    process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY
    process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET
    process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET
  }
}

function removeNodeModules() {
  if (fingerprint.fingerprintMatches()) {
    console.log('node_modules matches current fingerprint ' + fingerprint.fingerprint() + ' - not removing')
    return
  }

  var fsPlus;
  try {
    fsPlus = require('fs-plus');
  } catch (error) {
    return;
  }

  try {
    fsPlus.removeSync(path.resolve(__dirname, '..', 'node_modules'));
  } catch (error) {
    console.error(error.message);
    process.exit(1);
  }
}

function removeTempFolders() {
  var fsPlus;
  try {
    fsPlus = require('fs-plus');
  } catch (error) {
    return;
  }

  var temp = require('os').tmpdir();
  if (!fsPlus.isDirectorySync(temp))
    return;

  var deletedFolders = 0;

  fsPlus.readdirSync(temp).filter(function(folderName) {
    return folderName.indexOf('npm-') === 0;
  }).forEach(function(folderName) {
    try {
      fsPlus.removeSync(path.join(temp, folderName));
      deletedFolders++;
    } catch (error) {
      console.error("Failed to delete npm temp folder: " + error.message);
    }
  });

  if (deletedFolders > 0)
    console.log("Deleted " + deletedFolders + " npm folders from temp directory");
}

readEnvironmentVariables();
setEnvironmentVariables();
removeNodeModules();
removeTempFolders();
cp.safeExec.bind(global, 'npm install npm --loglevel error', {cwd: path.resolve(__dirname, '..', 'build')}, function() {
  cp.safeExec.bind(global, 'node script/bootstrap', function(error) {
    if (error)
      process.exit(1);
    require('fs-plus').removeSync.bind(global, path.join(homeDir, '.atom'))
    var async = require('async');
    var gruntPath = path.join('build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : '');
    var tasks = [
      cp.safeExec.bind(global, 'git clean -dff -e node_modules'), // If we left them behind in removeNodeModules() they are OK to use
      cp.safeExec.bind(global, gruntPath + ' ci --gruntfile build/Gruntfile.coffee --stack --no-color')
    ]
    async.series(tasks, function(error) {
      process.exit(error ? 1 : 0);
    });
  })();
})();
